<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"chuangges.gitee.io","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"right","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":"mac"},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="输入密码查看：项目开发、AngularJS、环境部署、数据库操作">
<meta property="og:type" content="article">
<meta property="og:title" content="智能工厂">
<meta property="og:url" content="https://chuangges.gitee.io/2020/12/10/15-%E6%99%BA%E8%83%BD%E5%B7%A5%E5%8E%82/index.html">
<meta property="og:site_name" content="闯哥要去流浪了">
<meta property="og:description" content="输入密码查看：项目开发、AngularJS、环境部署、数据库操作">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://chuangges.gitee.io/images/web/gateway.png">
<meta property="article:published_time" content="2020-12-10T06:23:14.000Z">
<meta property="article:modified_time" content="2023-08-11T02:22:14.600Z">
<meta property="article:author" content="chuangges">
<meta property="article:tag" content="前端技术栈">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://chuangges.gitee.io/images/web/gateway.png">

<link rel="canonical" href="https://chuangges.gitee.io/2020/12/10/15-%E6%99%BA%E8%83%BD%E5%B7%A5%E5%8E%82/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>智能工厂 | 闯哥要去流浪了</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/atom.xml" title="闯哥要去流浪了" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">闯哥要去流浪了</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">愿你岁月可回首，且以深情共白头</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://chuangges.gitee.io/2020/12/10/15-%E6%99%BA%E8%83%BD%E5%B7%A5%E5%8E%82/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/chuang.png">
      <meta itemprop="name" content="chuangges">
      <meta itemprop="description" content="chuangge's blog.">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="闯哥要去流浪了">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          智能工厂
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-12-10 14:23:14" itemprop="dateCreated datePublished" datetime="2020-12-10T14:23:14+08:00">2020-12-10</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2023-08-11 10:22:14" itemprop="dateModified" datetime="2023-08-11T10:22:14+08:00">2023-08-11</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E5%89%8D%E7%AB%AF%E6%8A%80%E6%9C%AF%E6%A0%88/" itemprop="url" rel="index"><span itemprop="name">前端技术栈</span></a>
                </span>
            </span>

          <br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="far fa-file-word"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>34k</span>
            </span>
            <span class="post-meta-item" title="阅读时长">
              <span class="post-meta-item-icon">
                <i class="far fa-clock"></i>
              </span>
                <span class="post-meta-item-text">阅读时长 &asymp;</span>
              <span>31 分钟</span>
            </span>
            <div class="post-description">输入密码查看：项目开发、AngularJS、环境部署、数据库操作</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="一、项目开发"><a href="#一、项目开发" class="headerlink" title="一、项目开发"></a>一、项目开发</h1><blockquote>
<p>智能工厂 DC 是基于 MEAN (MongoDB + Express + Angular + Node.js) 框架扩展的全栈开发，主要包括：前端应用组件、Model 层、Service 层、后台通用 CRUD、事物扩展等。</p>
</blockquote>
<h2 id="开发准备"><a href="#开发准备" class="headerlink" title="开发准备"></a>开发准备</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、mac 安装 Node 环境</span></span><br><span class="line"><span class="comment">// 2、安装并配置 MongoDB</span></span><br><span class="line"><span class="comment">// 3、安装 git、下载项目代码</span></span><br><span class="line"><span class="comment">// 4、安装工具和依赖</span></span><br><span class="line">npm install -g gulp bower yo generator-umif-app</span><br><span class="line">npm install、bower install</span><br></pre></td></tr></table></figure>

<h2 id="应用开发"><a href="#应用开发" class="headerlink" title="应用开发"></a>应用开发</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 新建应用</span></span><br><span class="line">yo umif-app</span><br><span class="line">gulp init --id=<span class="title class_">NewApp</span> --name=中文名</span><br><span class="line">gulp init --id=<span class="title class_">TypeScriptApp</span> --name=中文名 --ts</span><br><span class="line"></span><br><span class="line"><span class="comment">// 运行模式：debug、release</span></span><br><span class="line">gulp serve、gulp <span class="attr">serve</span>:dist</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 打包应用：apps 目录下生成 NewApp.zip</span></span><br><span class="line">gulp pack --app=<span class="title class_">NewApp</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> 打包时的代码编译方案</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@prame</span> babel：将 ES6+ 代码编译转换为 JS，但不会转化 BOM 不兼容的 API</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@prame</span> <span class="variable">babel</span>-preset-env：指定代码执行环境，并且只编译该环境缺少的特性</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@prame</span> polyfill：打包时编译转换 Promise、Set、Symbol、async 等语法</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line">cnpm install gulp gulp-babel babel-preset-env babel-core --save-dev</span><br><span class="line">gulp.<span class="title function_">src</span>().<span class="title function_">pipe</span>(<span class="title function_">babel</span>(&#123;  <span class="attr">presets</span>: [<span class="string">&#x27;env&#x27;</span>]  &#125;))</span><br><span class="line">&lt;script src=<span class="string">&quot;js/polyfill.js&quot;</span>&gt;&lt;/script&gt;</span><br></pre></td></tr></table></figure>


<h2 id="查询优化"><a href="#查询优化" class="headerlink" title="查询优化"></a>查询优化</h2><ul>
<li>尽量将能缩小范围的条件排在前面，减少数据的命中范围而提高查询效率。</li>
<li>尽量少用 $or 和 $ne 来进行过滤，尽量避免使用关联表来进行查询。</li>
<li>Populate 关联表查询时尽量减少查询数据，要加上 select 选项。</li>
<li>尽量减少查询数据库的次数，避免在 for 循环里查询数据多次数据库。</li>
<li>查找、赋值用到枚举值类型时为方便维护使用枚举值，不要直接写数字。</li>
<li>必须使用 try、catch 捕获代码错误，并在 catch 中写错误日志。</li>
</ul>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 数据保存</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">submitData</span> = <span class="keyword">async</span> <span class="keyword">function</span> (<span class="params">req, res</span>) &#123;</span><br><span class="line">    <span class="keyword">let</span> app = req.<span class="property">body</span>.<span class="property">app</span></span><br><span class="line">    <span class="keyword">let</span> user = req.<span class="property">body</span>.<span class="property">user</span>;</span><br><span class="line">    <span class="keyword">let</span> terminal = req.<span class="property">body</span>.<span class="property">terminal</span>;</span><br><span class="line">    <span class="keyword">let</span> sessionId = <span class="title class_">BaseFun</span>.<span class="title function_">sessionId</span>();</span><br><span class="line">    <span class="keyword">let</span> newErr = <span class="keyword">new</span> <span class="title class_">Error</span>();</span><br><span class="line">        newErr.<span class="property">leval</span> = <span class="number">9</span>;</span><br><span class="line">        newErr.<span class="property">title</span> = <span class="string">&quot;参数错误&quot;</span>;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        centerBizLogMsg (app, user, terminal, <span class="string">&#x27;submitData&#x27;</span>, req.<span class="property">body</span>)</span><br><span class="line">        <span class="keyword">let</span> <span class="title class_">PrintAssign</span> = <span class="keyword">await</span> entityFun.<span class="title function_">findOne</span>(<span class="string">&#x27;PrintAssign&#x27;</span>, &#123;</span><br><span class="line">            <span class="title class_">AppId</span>: app &amp;&amp; app.<span class="property">AppID</span>,</span><br><span class="line">            <span class="title class_">PrintPoint</span>: <span class="number">0</span></span><br><span class="line">        &#125;);</span><br><span class="line">        <span class="keyword">if</span> (!<span class="title class_">PrintAssign</span>) &#123;</span><br><span class="line">            newErr.<span class="property">message</span> = <span class="string">&#x27;请配置打印模版&#x27;</span></span><br><span class="line">            res.<span class="title function_">json</span>(&#123; <span class="title class_">Data</span>: <span class="literal">true</span>, <span class="title class_">Error</span>: <span class="literal">null</span> &#125;);</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">let</span> saveData = [&#123; <span class="title class_">EntityName</span>: <span class="string">&#x27;JobSchedule&#x27;</span>, <span class="title class_">Records</span>: <span class="title class_">JobArray</span> &#125;]</span><br><span class="line">        <span class="keyword">let</span> _saveData = [&#123; <span class="title class_">EntityName</span>: <span class="string">&#x27;QCTask&#x27;</span>, <span class="title class_">Records</span>: <span class="title class_">QCTaskArray</span> &#125;]</span><br><span class="line">        <span class="keyword">await</span> entityFun.<span class="title function_">batchSaveByTran</span>(saveData, sessionId)</span><br><span class="line">        <span class="keyword">await</span> entityFun.<span class="title function_">batchSaveByTran</span>(_saveData, sessionId)</span><br><span class="line">        res.<span class="title function_">json</span>(&#123; <span class="title class_">Data</span>: <span class="literal">true</span>, <span class="title class_">Error</span>: <span class="literal">null</span> &#125;);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">        transaction.<span class="title class_">Rollback</span>(sessionId);</span><br><span class="line">        newErr.<span class="property">message</span> = error.<span class="property">message</span>;</span><br><span class="line">        res.<span class="title function_">json</span>(&#123; <span class="title class_">Data</span>: <span class="literal">null</span>, <span class="title class_">Error</span>: newErr &#125;)</span><br><span class="line">        <span class="title function_">centerBizLogMsg</span>(app, user, terminal, <span class="string">&#x27;submitData&#x27;</span>, error.<span class="property">message</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数据回滚</span></span><br><span class="line"><span class="keyword">var</span> entityInsertMap = <span class="keyword">new</span> <span class="title class_">Map</span>();      <span class="comment">// 用于记录一次新增提交的数据集合</span></span><br><span class="line"><span class="keyword">var</span> entityUpdateMap = <span class="keyword">new</span> <span class="title class_">Map</span>();      <span class="comment">// 用于记录一次修改提交的数据集合</span></span><br><span class="line"><span class="keyword">var</span> entityDeleteMap = <span class="keyword">new</span> <span class="title class_">Map</span>();      <span class="comment">// 用于记录一次删除提交的数据集合</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">rollback</span> (sessionId) &#123;</span><br><span class="line">    <span class="keyword">let</span> deleteRecords = entityDeleteMap.<span class="title function_">get</span>(sessionId);</span><br><span class="line">    <span class="keyword">let</span> updateRecords = entityUpdateMap.<span class="title function_">get</span>(sessionId);</span><br><span class="line">    <span class="keyword">let</span> insertRecords = entityInsertMap.<span class="title function_">get</span>(sessionId);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> entityName <span class="keyword">in</span> deleteRecords) &#123;</span><br><span class="line">      <span class="keyword">var</span> entity = entityCollection.<span class="title function_">getEntity</span>(entityName);</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; deleteRecords[entityName].<span class="property">length</span>; i++) &#123;</span><br><span class="line">          entity.<span class="property">Entity</span>.<span class="title function_">deleteOne</span>(&#123; </span><br><span class="line">              <span class="attr">_id</span>: deleteRecords[entityName][i].<span class="property">_id</span> </span><br><span class="line">          &#125;).<span class="title function_">exec</span>();</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> entityName <span class="keyword">in</span> updateRecords) &#123;</span><br><span class="line">        <span class="keyword">var</span> entity = entityCollection.<span class="title function_">getEntity</span>(entityName);</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; updateRecords[entityName].<span class="property">length</span>; i++) &#123;</span><br><span class="line">            entity.<span class="property">Entity</span>.<span class="title function_">update</span>(</span><br><span class="line">                &#123; <span class="attr">_id</span>: updateRecords[entityName][i].<span class="property">_id</span> &#125;, </span><br><span class="line">                &#123; <span class="attr">$set</span>: updateRecords[entityName][i] &#125;, </span><br><span class="line">                &#123; <span class="attr">overwrite</span>: <span class="literal">true</span> &#125;</span><br><span class="line">            ).<span class="title function_">exec</span>();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> entityName <span class="keyword">in</span> insertRecords) &#123;</span><br><span class="line">      <span class="keyword">var</span> entity = entityCollection.<span class="title function_">getEntity</span>(entityName);</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; insertRecords[entityName].<span class="property">length</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">var</span> newEntity = <span class="keyword">new</span> entity.<span class="title class_">Entity</span>(insertRecords[entityName][i]);</span><br><span class="line">        newEntity.<span class="title function_">save</span>();</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    entityDeleteMap.<span class="title function_">delete</span>(sessionId);</span><br><span class="line">    entityInsertMap.<span class="title function_">delete</span>(sessionId);</span><br><span class="line">    entityUpdateMap.<span class="title function_">delete</span>(sessionId);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询方法</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">find</span> = <span class="keyword">function</span> (<span class="params">entityName, condition, sort, populate</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="keyword">function</span> (<span class="params">resolve, reject</span>) &#123;</span><br><span class="line">        <span class="comment">// _entityCollection 为包含所有实体的对象</span></span><br><span class="line">        <span class="keyword">var</span> entity = _entityCollection[entityName];</span><br><span class="line">        <span class="keyword">if</span>(entity == <span class="literal">undefined</span> || entity == <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;警告：实体 &quot;</span> + entityName + <span class="string">&quot; 不存在，请检查程序&quot;</span>);</span><br><span class="line">            entity = <span class="literal">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        entity.<span class="title function_">find</span>(condition, sort, populate, <span class="keyword">function</span> (<span class="params">err, records</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (err) &#123;</span><br><span class="line">                <span class="keyword">let</span> newErr = <span class="keyword">new</span> <span class="title class_">Error</span>();</span><br><span class="line">                newErr.<span class="property">leval</span> = <span class="number">9</span>;</span><br><span class="line">                newErr.<span class="property">title</span> = <span class="string">&#x27;查询错误&#x27;</span> + entityName;</span><br><span class="line">                newErr.<span class="property">message</span> = <span class="string">&#x27;语法错误，请检查查询参数！&#x27;</span> + err.<span class="property">message</span>;</span><br><span class="line">                <span class="title function_">reject</span>(newErr);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="title function_">resolve</span>(records);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 打印日志</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">centerBizLogMsg</span> (app, user, terminal, url, data) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!app)&#123; <span class="keyword">return</span> &#125;</span><br><span class="line">    <span class="keyword">let</span> error = <span class="keyword">typeof</span> data == <span class="string">&#x27;string&#x27;</span> ? <span class="literal">true</span> : <span class="literal">false</span></span><br><span class="line">    <span class="keyword">let</span> paramLog = &#123;</span><br><span class="line">        <span class="title class_">AppID</span>: app.<span class="property">AppID</span>,</span><br><span class="line">        <span class="title class_">AppName</span>: app.<span class="property">Name</span>,</span><br><span class="line">        <span class="title class_">Terminal</span>: terminal,</span><br><span class="line">        <span class="title class_">Message</span>: error ? data : <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(data),</span><br><span class="line">        <span class="title class_">Level</span>: error ? <span class="number">2</span> : <span class="number">3</span>,</span><br><span class="line">        <span class="title class_">Operator</span>: user.<span class="property">Code</span>,</span><br><span class="line">        <span class="attr">URL</span>: <span class="string">`/api/<span class="subst">$&#123;app.AppID&#125;</span>/<span class="subst">$&#123;url&#125;</span>`</span></span><br><span class="line">    &#125;;</span><br><span class="line">    centerBizLog.<span class="title function_">createCenterBizLog</span>(paramLog);</span><br><span class="line">    <span class="keyword">if</span> (error) &#123; <span class="title class_">BaseFun</span>.<span class="title function_">errorLog</span>(<span class="string">`<span class="subst">$&#123;app.Name&#125;</span> <span class="subst">$&#123;url&#125;</span> 错误：<span class="subst">$&#123;data&#125;</span>`</span>) &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 日志记录</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">createCenterBizLog</span> (data) &#123;</span><br><span class="line">    <span class="keyword">let</span> appLog = <span class="keyword">await</span> entityFun.<span class="title function_">findOne</span>(<span class="string">&#x27;AppLogController&#x27;</span>, &#123; </span><br><span class="line">        <span class="title class_">AppID</span>: data.<span class="property">AppID</span>, </span><br><span class="line">        <span class="title class_">IsLogger</span>: <span class="literal">true</span> </span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">if</span> (appLog) &#123;</span><br><span class="line">        <span class="keyword">let</span> log = <span class="title class_">Object</span>.<span class="title function_">assign</span>(&#123;&#125;, data);</span><br><span class="line">        log.<span class="property">CreatedOn</span> = <span class="keyword">new</span> <span class="title class_">Date</span>();</span><br><span class="line">        log.<span class="property">CreatedBy</span> = data.<span class="property">Operator</span>;</span><br><span class="line">        log.<span class="property">RowStatus</span> = <span class="title class_">BaseEnum</span>.<span class="property">RowStatus</span>.<span class="property">Insert</span>.<span class="property">Value</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            entityFun.<span class="title function_">batchSaveByTran</span>([&#123; </span><br><span class="line">                <span class="title class_">EntityName</span>: <span class="string">&#x27;CenterBizLog&#x27;</span>, </span><br><span class="line">                <span class="title class_">Records</span>: [log] </span><br><span class="line">            &#125;]);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">            <span class="title class_">BaseFun</span>.<span class="title function_">errorLog</span>(<span class="string">&#x27;中央日志错误&#x27;</span>, error.<span class="property">message</span>, data.<span class="property">Operator</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 生成实体的随机 id</span></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">getObjectId</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> mongoose.<span class="property">Types</span>.<span class="title class_">ObjectId</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="gulp-配置"><a href="#gulp-配置" class="headerlink" title="gulp 配置"></a>gulp 配置</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// =================== pdaApp/gulpfile.js =========================</span></span><br><span class="line"><span class="keyword">const</span> &#123; readFileSync, writeFileSync, remove, removeSync, existsSync, </span><br><span class="line">renameSync, copySync &#125; = <span class="built_in">require</span>(<span class="string">&#x27;fs-extra&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> &#123; join &#125; = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> gulp = <span class="built_in">require</span>(<span class="string">&#x27;gulp&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> gulpLoadPlugins = <span class="built_in">require</span>(<span class="string">&#x27;gulp-load-plugins&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> browserSync = <span class="built_in">require</span>(<span class="string">&#x27;browser-sync&#x27;</span>).<span class="title function_">create</span>();</span><br><span class="line"><span class="keyword">const</span> del = <span class="built_in">require</span>(<span class="string">&#x27;del&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> wiredep = <span class="built_in">require</span>(<span class="string">&#x27;wiredep&#x27;</span>).<span class="property">stream</span>;</span><br><span class="line"><span class="keyword">const</span> stylish = <span class="built_in">require</span>(<span class="string">&#x27;jshint-stylish&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> runSequence = <span class="built_in">require</span>(<span class="string">&#x27;run-sequence&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> through2 = <span class="built_in">require</span>(<span class="string">&#x27;through2&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> $ = <span class="title function_">gulpLoadPlugins</span>(&#123;</span><br><span class="line">    <span class="attr">rename</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;gulp-angular-templatecache&#x27;</span>: <span class="string">&#x27;templateCache&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">const</span> reload = browserSync.<span class="property">reload</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 处理命令行参数</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param</span> &#123;<span class="type">string[]</span>&#125; argv 命令行参数列表</span></span><br><span class="line"><span class="comment">* <span class="doctag">@returns</span> &#123;<span class="type">&#123; _: string[]; [arg: string]: string | boolean </span>&#125;&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">resolveArgv</span> (argv) &#123;</span><br><span class="line">    <span class="keyword">const</span> args = &#123; <span class="attr">_</span>: [] &#125;;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; argv.<span class="property">length</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (argv[i].<span class="title function_">slice</span>(<span class="number">0</span>, <span class="number">2</span>) === <span class="string">&#x27;--&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (argv[i][<span class="number">2</span>] === <span class="string">&#x27;_&#x27;</span>) process.<span class="title function_">exit</span>(<span class="number">0</span>);</span><br><span class="line">            <span class="keyword">if</span> (!argv[i].<span class="title function_">includes</span>(<span class="string">&#x27;=&#x27;</span>)) &#123;</span><br><span class="line">                args[argv[i].<span class="title function_">slice</span>(<span class="number">2</span>)] = <span class="literal">true</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">const</span> [key, value] = argv[i].<span class="title function_">split</span>(<span class="string">&#x27;=&#x27;</span>);</span><br><span class="line">                args[key.<span class="title function_">slice</span>(<span class="number">2</span>)] = value;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            args.<span class="property">_</span>.<span class="title function_">push</span>(argv[i]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> args;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;init&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> args = <span class="title function_">resolveArgv</span>(process.<span class="property">argv</span>.<span class="title function_">slice</span>(<span class="number">3</span>));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!args.<span class="property">id</span> || !args.<span class="property">name</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Usage:\n\n  gulp init --id=appID --name=appName`</span>);</span><br><span class="line">        process.<span class="title function_">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">const</span> appID = args.<span class="property">id</span>;</span><br><span class="line">    <span class="keyword">const</span> appName = args.<span class="property">name</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="title function_">existsSync</span>(<span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>`</span>))) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;\n\n  应用已存在，请检查应用ID&#x27;</span>);</span><br><span class="line">        process.<span class="title function_">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> <span class="title function_">_template</span> = (<span class="params"></span>) =&gt; through2.<span class="title function_">obj</span>(<span class="keyword">function</span>(<span class="params">file, _encoding, cb</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (file.<span class="title function_">isNull</span>()) &#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="title function_">push</span>(file);</span><br><span class="line">            <span class="keyword">return</span> <span class="title function_">cb</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (file.<span class="title function_">isStream</span>()) &#123;</span><br><span class="line">            <span class="variable language_">this</span>.<span class="title function_">emit</span>(<span class="string">&#x27;error&#x27;</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="title function_">cb</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">var</span> content = file.<span class="property">contents</span>.<span class="title function_">toString</span>()</span><br><span class="line">                      .<span class="title function_">replace</span>(<span class="regexp">/\&#123;\&#123;**ID**\&#125;\&#125;/g</span>, appID)</span><br><span class="line">                      .<span class="title function_">replace</span>(<span class="regexp">/\&#123;\&#123;**NAME**\&#125;\&#125;/g</span>, appName);</span><br><span class="line">        file.<span class="property">contents</span> = <span class="title class_">Buffer</span>.<span class="title function_">from</span>(content);</span><br><span class="line">        <span class="variable language_">this</span>.<span class="title function_">push</span>(file);</span><br><span class="line">        <span class="title function_">cb</span>();</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> <span class="title function_">renamePng</span> = (<span class="params"></span>) =&gt; <span class="title function_">renameSync</span>(</span><br><span class="line">              <span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/&#123;&#123;**ID**&#125;&#125;.png`</span>),</span><br><span class="line">              <span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/<span class="subst">$&#123;appID&#125;</span>.png`</span>)</span><br><span class="line">          );</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (args.<span class="property">ts</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> gulp.<span class="title function_">src</span>([</span><br><span class="line">            <span class="string">`template/.gitignore`</span>,</span><br><span class="line">            <span class="string">`template/**/*`</span>,</span><br><span class="line">            <span class="string">`!template/js`</span>,</span><br><span class="line">            <span class="string">`!template/js/**/*`</span></span><br><span class="line">        ])</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;**/*.?(html|js|ts)&#x27;</span>, <span class="title function_">_template</span>()))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>`</span>))</span><br><span class="line">        .<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, renamePng);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> gulp.<span class="title function_">src</span>([</span><br><span class="line">            <span class="string">`template/**/*`</span>,</span><br><span class="line">            <span class="string">`!template/ts`</span>,</span><br><span class="line">            <span class="string">`!template/ts/**/*`</span>,</span><br><span class="line">            <span class="string">`!template/tsconfig.json`</span></span><br><span class="line">        ])</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;**/*.?(html|js|ts)&#x27;</span>, <span class="title function_">_template</span>()))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>`</span>))</span><br><span class="line">        .<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, renamePng);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;pack&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> args = <span class="title function_">resolveArgv</span>(process.<span class="property">argv</span>.<span class="title function_">slice</span>(<span class="number">3</span>));</span><br><span class="line">    <span class="keyword">if</span> (!args.<span class="property">app</span>) &#123;</span><br><span class="line">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Usage:\n\n  gulp pack --app=appID`</span>);</span><br><span class="line">        process.<span class="title function_">exit</span>(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">const</span> appID = args.<span class="property">app</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="title function_">existsSync</span>(<span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>))) &#123;</span><br><span class="line">        <span class="title function_">removeSync</span>(<span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> preConcat = [</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/app.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/controllers/controllers.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/directives/directives.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/filters/filters.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/services/services.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/js/utility/utility.js`</span></span><br><span class="line">    ];</span><br><span class="line">    <span class="keyword">const</span> src = [</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack/js/app.tmp.js`</span>,</span><br><span class="line">        <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/**/*`</span>,</span><br><span class="line">        ...(preConcat.<span class="title function_">map</span>(<span class="function"><span class="params">r</span> =&gt;</span> <span class="string">`!<span class="subst">$&#123;r&#125;</span>`</span>)),</span><br><span class="line">        <span class="string">`!apps/<span class="subst">$&#123;appID&#125;</span>/ts`</span>,</span><br><span class="line">        <span class="string">`!apps/<span class="subst">$&#123;appID&#125;</span>/ts/**/*`</span>,</span><br><span class="line">        <span class="string">`!apps/<span class="subst">$&#123;appID&#125;</span>/**/*.map`</span>,</span><br><span class="line">        <span class="string">`!apps/<span class="subst">$&#123;appID&#125;</span>/tsconfig.json`</span>,</span><br><span class="line">        <span class="string">`!apps/<span class="subst">$&#123;appID&#125;</span>/.gitignore`</span></span><br><span class="line">    ];</span><br><span class="line">    <span class="keyword">const</span> babelConfig = &#123; <span class="attr">presets</span>: [<span class="string">&#x27;env&#x27;</span>] &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(preConcat)</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(!<span class="title function_">existsSync</span>(<span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/tsconfig.json`</span>)), </span><br><span class="line">              $.<span class="title function_">babel</span>(babelConfig)))</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">uglify</span>())</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">concat</span>(<span class="string">`js/app.tmp.js`</span>, &#123; <span class="attr">newLine</span>: <span class="string">&#x27;;&#x27;</span> &#125;))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>))</span><br><span class="line">        .<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">const</span> <span class="title function_">getPath</span> = (<span class="params">...p</span>) =&gt; <span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>, ...p);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">let</span> code = <span class="title function_">readFileSync</span>(<span class="title function_">getPath</span>(<span class="string">&#x27;js/app.tmp.js&#x27;</span>), <span class="string">&#x27;utf8&#x27;</span>);</span><br><span class="line">            <span class="keyword">let</span> target = code.<span class="title function_">match</span>(<span class="regexp">/umifpda.registerModule\(.*?(,&#123;.*?&#125;).*?\)/</span>)[<span class="number">1</span>];</span><br><span class="line">            <span class="keyword">if</span> (!target) &#123;</span><br><span class="line">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;检查umifpda.registerModule()数组参数最后一个元素是否对象&#x27;</span>);</span><br><span class="line">                process.<span class="title function_">exit</span>(<span class="number">0</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">let</span> resolvedCode = code.<span class="title function_">replace</span>(target, <span class="string">&#x27;&#x27;</span>);</span><br><span class="line">            <span class="title function_">writeFileSync</span>(<span class="title function_">getPath</span>(<span class="string">&#x27;js/app.tmp.js&#x27;</span>), resolvedCode);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> gulp.<span class="title function_">src</span>(src)</span><br><span class="line">                .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.js&#x27;</span>, $.<span class="title function_">if</span>(</span><br><span class="line">                    !<span class="title function_">existsSync</span>(<span class="title function_">join</span>(**dirname, <span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>/tsconfig.json`</span>)), </span><br><span class="line">                    $.<span class="title function_">babel</span>(babelConfig))</span><br><span class="line">                ))</span><br><span class="line">                .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.js&#x27;</span>, $.<span class="title function_">uglify</span>()))</span><br><span class="line">                .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.js&#x27;</span>, $.<span class="title function_">concat</span>(<span class="string">`js/app.js`</span>, &#123; <span class="attr">newLine</span>: <span class="string">&#x27;;&#x27;</span> &#125;)))</span><br><span class="line">                .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.css&#x27;</span>, $.<span class="title function_">cssnano</span>(&#123;<span class="attr">safe</span>: <span class="literal">true</span>, <span class="attr">autoprefixer</span>: <span class="literal">false</span>&#125;)))</span><br><span class="line">                .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.html&#x27;</span>, $.<span class="title function_">htmlmin</span>(&#123; <span class="attr">collapseWhitespace</span>: <span class="literal">true</span> &#125;)))</span><br><span class="line">                .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>))</span><br><span class="line">                .<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, <span class="function">() =&gt;</span> <span class="title class_">Promise</span>.<span class="title function_">all</span>(([</span><br><span class="line">                    <span class="string">&#x27;js/app.tmp.js&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;js/controllers&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;js/directives&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;js/filters&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;js/services&#x27;</span>,</span><br><span class="line">                    <span class="string">&#x27;js/utility&#x27;</span></span><br><span class="line">                ])</span><br><span class="line">                .<span class="title function_">map</span>(<span class="function"><span class="params">p</span> =&gt;</span> <span class="title function_">remove</span>(<span class="title function_">getPath</span>(p))))</span><br><span class="line">                .<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123; </span><br><span class="line">                    <span class="title function_">copySync</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>, <span class="string">`apps/tmp/<span class="subst">$&#123;appID&#125;</span>`</span>)</span><br><span class="line">                    gulp.<span class="title function_">src</span>(<span class="string">`apps/tmp/**/*`</span>)</span><br><span class="line">                    .<span class="title function_">pipe</span>($.<span class="title function_">zip</span>(<span class="string">`<span class="subst">$&#123;appID&#125;</span>.zip`</span>))</span><br><span class="line">                    .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;apps&#x27;</span>))</span><br><span class="line">                    .<span class="title function_">on</span>(<span class="string">&#x27;end&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">                        <span class="title function_">removeSync</span>(<span class="string">`apps/<span class="subst">$&#123;appID&#125;</span>.pack`</span>)</span><br><span class="line">                        <span class="title function_">removeSync</span>(<span class="string">`apps/tmp`</span>)</span><br><span class="line">                    &#125;)</span><br><span class="line">                &#125;));</span><br><span class="line">        &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;lint&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>([<span class="string">&#x27;app/js/**/*.js&#x27;</span>, <span class="string">&#x27;!app/js/polyfill.min.js&#x27;</span>])</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">jshint</span>())</span><br><span class="line">          .<span class="title function_">pipe</span>($.jshint.<span class="title function_">reporter</span>(stylish));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;html&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">var</span> partialsInjectFile = gulp.<span class="title function_">src</span>(<span class="string">&#x27;.tmp/templates.js&#x27;</span>, &#123;<span class="attr">read</span>: <span class="literal">false</span>&#125;);</span><br><span class="line">    <span class="keyword">var</span> partialsInjectOptions = &#123;</span><br><span class="line">        <span class="attr">starttag</span>: <span class="string">&#x27;&lt;!-- inject:templates --&gt;&#x27;</span>,</span><br><span class="line">        <span class="attr">ignorePath</span>: <span class="string">&#x27;.tmp&#x27;</span>,</span><br><span class="line">        <span class="attr">addRootSlash</span>: <span class="literal">false</span></span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/*.html&#x27;</span>)</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">inject</span>(partialsInjectFile, partialsInjectOptions))</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">useref</span>())</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.js&#x27;</span>, $.<span class="title function_">uglify</span>()))</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.css&#x27;</span>, $.<span class="title function_">cssnano</span>(&#123;<span class="attr">safe</span>: <span class="literal">true</span>, <span class="attr">autoprefixer</span>: <span class="literal">false</span>&#125;)))</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">if</span>(<span class="string">&#x27;*.html&#x27;</span>, $.<span class="title function_">htmlmin</span>(&#123;<span class="attr">collapseWhitespace</span>: <span class="literal">true</span>&#125;)))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;images&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/img/**/*&#x27;</span>)</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">cache</span>($.<span class="title function_">imagemin</span>()))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www/img&#x27;</span>));</span><br><span class="line">&#125;)</span><br><span class="line">;</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;fonts&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="built_in">require</span>(<span class="string">&#x27;main-bower-files&#x27;</span>)(<span class="string">&#x27;**/*.&#123;eot,svg,ttf,woff,woff2&#125;&#x27;</span>,</span><br><span class="line">    <span class="keyword">function</span> (<span class="params">err</span>) &#123; &#125;))</span><br><span class="line">    .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www/fonts&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;depimages&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="built_in">require</span>(<span class="string">&#x27;main-bower-files&#x27;</span>)(<span class="string">&#x27;**/*.&#123;png,jpg,jpeg,gif,webp&#125;&#x27;</span>, </span><br><span class="line">    <span class="keyword">function</span> (<span class="params">err</span>) &#123; &#125;))</span><br><span class="line">    .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www/img&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;appfiles&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/**/*&#x27;</span>)</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;bowerfiles&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="built_in">require</span>(<span class="string">&#x27;main-bower-files&#x27;</span>)(<span class="string">&#x27;**/*&#x27;</span>), </span><br><span class="line">        &#123; <span class="attr">read</span>: <span class="literal">true</span>, <span class="attr">base</span>: <span class="string">&#x27;bower_components&#x27;</span> &#125;)</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www/bower_components&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Angular template cache task</span></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;templatecache&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/tpls/**/*.html&#x27;</span>)</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">templateCache</span>(<span class="string">&#x27;templates.js&#x27;</span>, &#123;</span><br><span class="line">            <span class="attr">root</span>: <span class="string">&#x27;tpls/&#x27;</span>,</span><br><span class="line">            <span class="attr">module</span>: <span class="string">&#x27;umifpda&#x27;</span></span><br><span class="line">        &#125;))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;.tmp&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;clean&#x27;</span>, del.<span class="title function_">bind</span>(<span class="literal">null</span>, [<span class="string">&#x27;.tmp&#x27;</span>, <span class="string">&#x27;www&#x27;</span>]));</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;serve&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">runSequence</span>([<span class="string">&#x27;clean&#x27;</span>, <span class="string">&#x27;wiredep&#x27;</span>, <span class="string">&#x27;lint&#x27;</span>], <span class="function">() =&gt;</span> &#123;</span><br><span class="line">            browserSync.<span class="title function_">init</span>(&#123;</span><br><span class="line">                <span class="attr">notify</span>: <span class="literal">false</span>,</span><br><span class="line">                <span class="attr">port</span>: <span class="number">9019</span>,</span><br><span class="line">                <span class="attr">server</span>: &#123;</span><br><span class="line">                    <span class="attr">baseDir</span>: [<span class="string">&#x27;app&#x27;</span>],</span><br><span class="line">                    <span class="attr">routes</span>: &#123;</span><br><span class="line">                        <span class="string">&#x27;/bower_components&#x27;</span>: <span class="string">&#x27;./bower_components&#x27;</span>,</span><br><span class="line">                        <span class="string">&#x27;/apps&#x27;</span>: <span class="string">&#x27;./apps&#x27;</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;);</span><br><span class="line"></span><br><span class="line">            gulp.<span class="title function_">watch</span>([</span><br><span class="line">                <span class="string">&#x27;app/css/**/*.css&#x27;</span>,</span><br><span class="line">                <span class="string">&#x27;app/js/**/*.js&#x27;</span>,</span><br><span class="line">                <span class="string">&#x27;app/tpls/**/*.html&#x27;</span>,</span><br><span class="line">                <span class="string">&#x27;app/*.html&#x27;</span>,</span><br><span class="line">                <span class="string">&#x27;app/img/**/*&#x27;</span></span><br><span class="line">            ]).<span class="title function_">on</span>(<span class="string">&#x27;change&#x27;</span>, reload);</span><br><span class="line"></span><br><span class="line">            gulp.<span class="title function_">watch</span>(<span class="string">&#x27;app/js/**/*.js&#x27;</span>, [<span class="string">&#x27;lint&#x27;</span>]);</span><br><span class="line">            gulp.<span class="title function_">watch</span>(<span class="string">&#x27;bower.json&#x27;</span>, [<span class="string">&#x27;wiredep&#x27;</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">    );</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;serve:dist&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">runSequence</span>(<span class="string">&#x27;dist&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">        browserSync.<span class="title function_">init</span>(&#123;</span><br><span class="line">            <span class="attr">notify</span>: <span class="literal">false</span>,</span><br><span class="line">            <span class="attr">port</span>: <span class="number">9020</span>,</span><br><span class="line">            <span class="attr">server</span>: &#123; <span class="attr">baseDir</span>: [<span class="string">&#x27;www&#x27;</span>] &#125;</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// inject bower components</span></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;wiredep&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/*.html&#x27;</span>)</span><br><span class="line">        .<span class="title function_">pipe</span>(<span class="title function_">wiredep</span>(&#123;</span><br><span class="line">            <span class="attr">exclude</span>: [<span class="string">&#x27;bootstrap.js&#x27;</span>],</span><br><span class="line">            <span class="attr">ignorePath</span>: <span class="regexp">/^(\.\.\/)*\.\./</span></span><br><span class="line">        &#125;))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;app&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;wiredepdebug&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    gulp.<span class="title function_">src</span>(<span class="string">&#x27;app/*.html&#x27;</span>)</span><br><span class="line">        .<span class="title function_">pipe</span>(<span class="title function_">wiredep</span>(&#123;</span><br><span class="line">            <span class="attr">exclude</span>: [<span class="string">&#x27;bootstrap.js&#x27;</span>],</span><br><span class="line">            <span class="attr">ignorePath</span>: <span class="regexp">/^(\.\.\/)*\.\.\//</span></span><br><span class="line">        &#125;))</span><br><span class="line">        .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;www&#x27;</span>));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;build&#x27;</span>, [<span class="string">&#x27;lint&#x27;</span>, <span class="string">&#x27;html&#x27;</span>, <span class="string">&#x27;images&#x27;</span>, <span class="string">&#x27;fonts&#x27;</span>, <span class="string">&#x27;depimages&#x27;</span>], <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(<span class="string">&#x27;www/**/*&#x27;</span>).<span class="title function_">pipe</span>($.<span class="title function_">size</span>(&#123;<span class="attr">title</span>: <span class="string">&#x27;build&#x27;</span>, <span class="attr">gzip</span>: <span class="literal">true</span>&#125;));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;default&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">runSequence</span>([<span class="string">&#x27;clean&#x27;</span>, <span class="string">&#x27;wiredep&#x27;</span>], [<span class="string">&#x27;bowerfiles&#x27;</span>, <span class="string">&#x27;appfiles&#x27;</span>], </span><br><span class="line">        <span class="string">&#x27;wiredepdebug&#x27;</span>, resolve);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;dist&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">runSequence</span>([<span class="string">&#x27;clean&#x27;</span>, <span class="string">&#x27;wiredep&#x27;</span>, <span class="string">&#x27;templatecache&#x27;</span>], <span class="string">&#x27;build&#x27;</span>, resolve);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// ====================== umif-css-pda/gulpfile.js =========================</span></span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> gulp = <span class="built_in">require</span>(<span class="string">&#x27;gulp&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> gulpLoadPlugins = <span class="built_in">require</span>(<span class="string">&#x27;gulp-load-plugins&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> del = <span class="built_in">require</span>(<span class="string">&#x27;del&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> stylish = <span class="built_in">require</span>(<span class="string">&#x27;jshint-stylish&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> runSequence = <span class="built_in">require</span>(<span class="string">&#x27;run-sequence&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> $ = <span class="title function_">gulpLoadPlugins</span>(&#123;</span><br><span class="line">    <span class="attr">rename</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;gulp-angular-filesort&#x27;</span>: <span class="string">&#x27;fileSort&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> config = &#123;</span><br><span class="line">    <span class="attr">src</span>: <span class="string">&#x27;src&#x27;</span>,</span><br><span class="line">    <span class="attr">styles</span>: <span class="string">&#x27;css&#x27;</span>,</span><br><span class="line">    <span class="attr">images</span>: <span class="string">&#x27;img&#x27;</span>,</span><br><span class="line">    <span class="attr">scripts</span>: <span class="string">&#x27;js&#x27;</span>,</span><br><span class="line">    <span class="attr">dist</span>: <span class="string">&#x27;dist&#x27;</span>,</span><br><span class="line">    <span class="attr">module</span>: <span class="string">&#x27;umif-css-hd&#x27;</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> banner = gulp.<span class="title function_">task</span>(<span class="string">&#x27;clean&#x27;</span>, del.<span class="title function_">bind</span>(<span class="literal">null</span>, [config.<span class="property">dist</span>]));</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;lint&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">src</span>, config.<span class="property">scripts</span> + <span class="string">&#x27;/**/*.js&#x27;</span>))</span><br><span class="line">        .<span class="title function_">pipe</span>($.<span class="title function_">jshint</span>())</span><br><span class="line">        .<span class="title function_">pipe</span>($.jshint.<span class="title function_">reporter</span>(stylish));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;styles&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">src</span>, config.<span class="property">styles</span> + <span class="string">&#x27;/**/*.css&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">concat</span>(config.<span class="property">module</span> + <span class="string">&#x27;.css&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">header</span>(banner))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">styles</span>)));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;cssnano&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">styles</span> + <span class="string">&#x27;/&#x27;</span> + </span><br><span class="line">           config.<span class="property">module</span> + <span class="string">&#x27;.css&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">rename</span>(config.<span class="property">module</span> + <span class="string">&#x27;.min.css&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">cssnano</span>(&#123; <span class="attr">safe</span>: <span class="literal">true</span>, <span class="attr">autoprefixer</span>: <span class="literal">false</span> &#125;))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">styles</span>)));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;images&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">src</span>, config.<span class="property">images</span> + <span class="string">&#x27;/**/*&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">cache</span>($.<span class="title function_">imagemin</span>()))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">images</span>)));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;scripts&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">src</span>, config.<span class="property">scripts</span> + <span class="string">&#x27;/**/*.js&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">fileSort</span>())</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">concat</span>(config.<span class="property">module</span> + <span class="string">&#x27;.js&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">header</span>(banner))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">scripts</span>)));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;uglify&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">scripts</span> + <span class="string">&#x27;/&#x27;</span> + </span><br><span class="line">           config.<span class="property">module</span> + <span class="string">&#x27;.js&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">rename</span>(config.<span class="property">module</span> + <span class="string">&#x27;.min.js&#x27;</span>))</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">uglify</span>())</span><br><span class="line">          .<span class="title function_">pipe</span>($.<span class="title function_">header</span>(banner))</span><br><span class="line">          .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, config.<span class="property">scripts</span>)));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;build&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">runSequence</span>(<span class="string">&#x27;lint&#x27;</span>, [<span class="string">&#x27;styles&#x27;</span>, <span class="string">&#x27;scripts&#x27;</span>, <span class="string">&#x27;images&#x27;</span>], </span><br><span class="line">        [<span class="string">&#x27;cssnano&#x27;</span>, <span class="string">&#x27;uglify&#x27;</span>], resolve);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;gzip&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> gulp.<span class="title function_">src</span>(path.<span class="title function_">join</span>(config.<span class="property">dist</span>, <span class="string">&#x27;/**/*&#x27;</span>))</span><br><span class="line">    .<span class="title function_">pipe</span>($.<span class="title function_">size</span>(&#123; <span class="attr">title</span>: <span class="string">&#x27;build&#x27;</span>, <span class="attr">gzip</span>: <span class="literal">true</span> &#125;));</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&#x27;dist&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function"><span class="params">resolve</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="title function_">runSequence</span>(<span class="string">&#x27;clean&#x27;</span>, <span class="string">&#x27;build&#x27;</span>, <span class="string">&#x27;gzip&#x27;</span>, resolve);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>


<h1 id="二、AngularJS"><a href="#二、AngularJS" class="headerlink" title="二、AngularJS"></a>二、AngularJS</h1><blockquote>
<p>Google 开源的 JS 框架，AngularJS、Angular 分别指版本 angular1.x、angular2.0+。</p>
</blockquote>
<h2 id="核心概念"><a href="#核心概念" class="headerlink" title="核心概念"></a>核心概念</h2><blockquote>
<p>模块、组件、服务是核心特性，其它特性则基于它们衍生而出。比如：组件与服务之间有依赖注入特性、模块为组件和服务提供了编译的上下文和指令、管道等功能、视图更新依赖于双向绑定、视图的变换通过路由机制实现组件切换。</p>
</blockquote>
<ul>
<li><strong>模块</strong>：将代码隔离为可复用的块，然后通过依赖注入将模块组织为一个完整的应用程序。<ul>
<li><strong>JS 模块</strong>：一个包含代码的独立文件，通过导入导出机制解决变量冲突和依赖关系。</li>
<li><strong>NgModule 模块</strong>：一个组织代码的类，通过装饰器和元数据将组件、指令、服务等代码组织为功能单元，主要用来启动 angular 应用。</li>
</ul>
</li>
<li><strong>组件</strong>：通过页面指令等模板语法实现和视图层交互，将数据请求等任务委托给服务。<ul>
<li><strong>数据绑定</strong>：将模板和组件类的属性、方法建立映射关系。四种使用形式：插值表达式、属性绑定、事件绑定、双向绑定。</li>
<li><strong>指令</strong>：向 HTML 元素添加自定义行为而实现动态视图。三种类型：结构指令（增删元素）、属性指令（修改属性）、组件（拥有模板的指令）。</li>
<li><strong>过滤器</strong>：一种将输入值根据预定规则转换为页面显示值的转换函数。</li>
</ul>
</li>
<li><strong>服务</strong>：封装了日志服务等公共方法的独立模块，通过依赖注入提供给专注业务的组件。</li>
<li><strong>依赖注入</strong>：在构造器创建组件时将依赖组件等以参数形式传入，组件内部直接使用依赖的功能，顶端依赖会首先构造则解决了空引用报错问题并降低了代码耦合度。</li>
</ul>
<h2 id="重要对象"><a href="#重要对象" class="headerlink" title="重要对象"></a>重要对象</h2><ul>
<li><strong>全局对象 angular</strong>：全局可以调用<ul>
<li>module：创建模块对象</li>
<li>copy、extend：拷贝数组、对象</li>
<li>forEach：遍历数组、对象</li>
<li>equals：两个对象是否相等</li>
<li>toJson、fromJson：序列化</li>
<li>bootstrap：手动启动 angular</li>
<li>lowercase、uppercase：字符串大小写转换</li>
<li>isString、isObject、isArray、equals：类型判断</li>
</ul>
</li>
<li>**模块对象 angular.module()**：当前模块可以调用<ul>
<li>config：配置模块，注入 provider&#x2F;constance&#x2F;内置服务</li>
<li>run：启动应用，初始化全局数据、支持注入所有服务</li>
<li>factory、service、provider、constant、value：服务</li>
<li>controller、filter、directive、animation：控制器、过滤器、指令、动画</li>
</ul>
</li>
<li><strong>作用域对象 $rootScope $scope</strong>：存储应用模型 ViewModel 的实例对象<ul>
<li>$rootScope：ng-app 默认创建的根作用域对象</li>
<li>$scope：ng-controller 默认创建的模块作用域对象</li>
</ul>
</li>
</ul>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">angular.<span class="title function_">module</span>(<span class="string">&#x27;App&#x27;</span>, [])</span><br><span class="line">.<span class="title function_">config</span>(<span class="keyword">function</span>(<span class="params">$provide, $compileProvider</span>)&#123;</span><br><span class="line">　　$provide.<span class="title function_">factory</span>(<span class="string">&#x27;myFactory&#x27;</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">　　　　<span class="keyword">return</span> &#123;&#125;;</span><br><span class="line">　　&#125;)</span><br><span class="line">    $compileProvider.<span class="title function_">directive</span>(<span class="string">&#x27;myDir&#x27;</span>, <span class="keyword">function</span>(<span class="params"></span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> &#123; <span class="attr">template</span>:<span class="string">&#x27;&lt;button&gt;click&lt;/button&gt;&#x27;</span> &#125;</span><br><span class="line">　　&#125;)</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">run</span>([<span class="string">&#x27;$http&#x27;</span>, <span class="string">&#x27;$rootScope&#x27;</span>, <span class="keyword">function</span> (<span class="params">$http, $rootScope</span>) &#123;</span><br><span class="line">    $http(&#123; <span class="attr">url</span>: <span class="string">&#x27;xxx.php&#x27;</span>, <span class="attr">method</span>: <span class="string">&#x27;get&#x27;</span> &#125;)</span><br><span class="line">    $rootScope.<span class="property">name</span> = <span class="string">&#x27;祖宗&#x27;</span>;</span><br><span class="line">&#125;])</span><br><span class="line"><span class="comment">// 数组标注：参数可自定义但顺序与数组的依赖服务名一致。</span></span><br><span class="line">.<span class="title function_">controller</span>(<span class="string">&quot;homeCtrl&quot;</span>, [<span class="string">&#x27;$scope&#x27;</span>, <span class="keyword">function</span>(<span class="params">$scope</span>) &#123;  &#125;])</span><br><span class="line"><span class="comment">// 隐式标注：参数名必须与服务名相同，但代码压缩后会报错。</span></span><br><span class="line">.<span class="title function_">controller</span>(<span class="string">&quot;detailCtrl&quot;</span>, <span class="keyword">function</span>(<span class="params">$scope, hello1</span>)&#123; &#125;)</span><br></pre></td></tr></table></figure>


<h2 id="指令"><a href="#指令" class="headerlink" title="指令"></a>指令</h2><blockquote>
<p>通过自定义 html 元素和属性实现扩展功能。注意：双括号是 ng-bind 的简写形式但存在数据闪烁问题，但单页面应用只有加载 index.html 时才存在该问题，所以 index.html 模板只使用 ng-bind、其它模板可以使用双括号、ng-bind。常用的内置指令如下：</p>
</blockquote>
<ul>
<li><strong>声明作用域</strong>：ng-app、ng-controller。</li>
<li><strong>数据绑定</strong>：双括号、ng-bind、ng-model、ng-init、ng-repeat。</li>
<li><strong>样式相关</strong>：ng-class、ng-style、ng-if、ng-show、ng-hide、ng-switch。</li>
<li><strong>表单功能</strong>：ng-value、ng-checked、ng-selected、ng-disabled、ng-readonly。</li>
<li><strong>事件绑定</strong>：ng-click、ng-change、ng-dblclick、ng-mousedown、ng-mouseenter、ng-mouseleave、ng-mousemove、ng-mouseover、ng-mouseup、ng-submit。</li>
<li><strong>其它指令</strong>：ng-src、ng-href、ng-include、ng-transclude。</li>
</ul>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 自定义元素：&lt;im-item-view name=&quot;常量&quot; value=&quot;变量&quot; onInput=&quot;方法&quot;&gt;</span></span><br><span class="line">angular.<span class="title function_">module</span>(<span class="string">&#x27;app&#x27;</span>)</span><br><span class="line">.<span class="title function_">directive</span>(<span class="string">&#x27;imItemView&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        <span class="attr">restrict</span>: <span class="string">&#x27;E&#x27;</span>,    <span class="comment">// 指令约束：A 属性、E 元素、C 类名、M 注释</span></span><br><span class="line">        <span class="attr">replace</span>: <span class="literal">true</span>,    <span class="comment">// 是否将当前页面元素替换为 template</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">          * 关联作用域</span></span><br><span class="line"><span class="comment">          * true：父作用域</span></span><br><span class="line"><span class="comment">          * false：创建新作用域，并继承父作用域</span></span><br><span class="line"><span class="comment">          * obj：创建隔离作用域，通过 @、=、&amp; 和父作用域通信</span></span><br><span class="line"><span class="comment">        **/</span></span><br><span class="line">        <span class="attr">scope</span>: &#123; </span><br><span class="line">            <span class="attr">name</span>: <span class="string">&#x27;@&#x27;</span>,    <span class="comment">// 单向绑定</span></span><br><span class="line">            <span class="attr">value</span>: <span class="string">&#x27;=?&#x27;</span>,  <span class="comment">// 双向绑定</span></span><br><span class="line">            <span class="attr">onInput</span>: <span class="string">&#x27;&amp;&#x27;</span>  <span class="comment">// scope 的函数返回值绑定父作用域 scope</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">template</span>: </span><br><span class="line">        <span class="string">`&lt;div class=&quot;im-item-view&quot; ng-switch=&quot;type&quot;&gt;</span></span><br><span class="line"><span class="string">            &lt;span ng-if=&quot;name&quot; class=&quot;label&quot;&gt;&#123;&#123;name&#125;&#125;&lt;/span&gt;</span></span><br><span class="line"><span class="string">            &lt;span class=&quot;transclude&quot; ng-transclude&gt;&lt;/span&gt;</span></span><br><span class="line"><span class="string">            &lt;input type=&quot;text&quot; ng-model=&quot;value&quot; ng-=&quot;onClickInput()&quot; /&gt;</span></span><br><span class="line"><span class="string">        &lt;/div&gt;`</span>,</span><br><span class="line">        <span class="attr">controller</span>: <span class="keyword">function</span> (<span class="params">$scope</span>) &#123;</span><br><span class="line">            $scope.<span class="property">onClickInput</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">                $scope.<span class="title function_">onClick</span>(&#123; <span class="attr">val</span>: $scope.<span class="property">value</span> &#125;)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>


<h2 id="过滤器"><a href="#过滤器" class="headerlink" title="过滤器"></a>过滤器</h2><blockquote>
<p>显示数据时对数据进行格式化或过滤，但不会真正改变原数据，常用的内置过滤器有：currency (货币处理)、date (日期格式化)、filter (子集)、limitTo (限制长度)、lowercase (小写)、uppercase (大写)、number (格式化数字)、orderBy (排序)。</p>
</blockquote>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> _date = $filter(<span class="string">&#x27;date&#x27;</span>)(date, <span class="string">&#x27;yyyyMMdd-HH:mm&#x27;</span>)</span><br><span class="line"><span class="keyword">let</span> _list = $filter(<span class="string">&#x27;filter&#x27;</span>)(list, <span class="keyword">function</span> (<span class="params">item</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (item[searchBy].<span class="title function_">indexOf</span>(query) !== -<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义指令</span></span><br><span class="line">angular.<span class="title function_">module</span>(<span class="string">&quot;myApp&quot;</span>, [])</span><br><span class="line">.<span class="title function_">filter</span>(<span class="string">&quot;myfilter&quot;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">list</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> list.<span class="title function_">filter</span>(<span class="function"><span class="params">item</span> =&gt;</span> item.<span class="property">value</span> &gt; <span class="number">0</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">&lt;div ng-repeat=<span class="string">&quot;item in list | myfilter&quot;</span>&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>


<h2 id="服务"><a href="#服务" class="headerlink" title="服务"></a>服务</h2><ul>
<li><p>内置服务：通过声明式依赖注入（定义形参）的方式引用。</p>
<ul>
<li><strong>$http</strong>：发送 http 请求</li>
<li><strong>$resource</strong>：创建一个和服务器端数据交互的对象</li>
<li><strong>$window</strong>：浏览器 window 元素的 jQuery 包装</li>
<li><strong>$document</strong>：浏览器 document 元素的 jQuery 包装</li>
<li><strong>$rootScope、$rootElement</strong>：根作用域、根元素的访问</li>
<li><strong>$cacheFactory</strong>：提供键&#x2F;值对放置到对象缓存</li>
<li><strong>$interval</strong>：提供对 window.setInterval 访问</li>
<li><strong>$timeout</strong>：提供对 window.setTimeout 访问</li>
<li><strong>$cookies</strong>：提供对浏览器的 cookie 的读写访问</li>
<li><strong>$animate</strong>：提供动画钩子来同时链接到基于 CSS、Js 的动画</li>
</ul>
</li>
<li><p>自定义服务</p>
<ul>
<li><strong>factory</strong>：返回基本类型或对象。</li>
<li><strong>service</strong>：返回对象，默认构建了一个空白对象。</li>
<li><strong>value</strong>：定义常量，值可以被修改，但不能被注入到 config。</li>
<li><strong>constant</strong>：定义常量。不可改变和装饰，可以被注入到任何地方。</li>
<li><strong>provider</strong>：可以注入到 config，必须使用 $get 返回一个对象。</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line">angular.<span class="title function_">module</span>(<span class="string">&#x27;myApp&#x27;</span>, [])</span><br><span class="line"><span class="comment">// 内置服务</span></span><br><span class="line">.<span class="title function_">controller</span>(<span class="string">&#x27;myCtrl&#x27;</span>, <span class="keyword">function</span>(<span class="params">$scope, $location</span>) &#123; </span><br><span class="line">    $scope.<span class="property">pageUrl</span> = $location.<span class="title function_">absUrl</span>();</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">// 自定义服务</span></span><br><span class="line">.<span class="title function_">value</span>(<span class="string">&#x27;myVal&#x27;</span>, <span class="string">&#x27;cisco&#x27;</span>)</span><br><span class="line">.<span class="title function_">value</span>(<span class="string">&#x27;user&#x27;</span>, &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">    <span class="attr">setName</span>: <span class="keyword">function</span>(<span class="params">name</span>)&#123;</span><br><span class="line">        <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">constant</span>(<span class="string">&#x27;VERSION&#x27;</span>, <span class="string">&#x27;1.0&#x27;</span>)</span><br><span class="line">.<span class="title function_">constant</span>(<span class="string">&#x27;VERSION&#x27;</span>, &#123; <span class="attr">VERSION</span>: <span class="string">&#x27;1.0&#x27;</span> &#125;)</span><br><span class="line"></span><br><span class="line">.<span class="title function_">factory</span>(<span class="string">&#x27;format&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">arg</span>) &#123;</span><br><span class="line">        <span class="keyword">var</span> str = <span class="string">&#x27;&#x27;</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">var</span> key <span class="keyword">in</span> arg)&#123;</span><br><span class="line">            str += key + <span class="string">&#x27;=&#x27;</span>+arg[key] +<span class="string">&#x27;&amp;&#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        str = str.<span class="title function_">slice</span>(<span class="number">0</span>,-<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">return</span> str;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">service</span>(<span class="string">&#x27;service&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">test</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123; &#125;</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">filter</span>(<span class="string">&#x27;leftTrim&#x27;</span>, <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">str</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> str.<span class="title function_">replace</span>(<span class="regexp">/^\s+/</span>, <span class="string">&#x27;&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br><span class="line">.<span class="title function_">provider</span>(<span class="string">&#x27;hello&#x27;</span>, <span class="keyword">function</span>(<span class="params"></span>) &#123;  </span><br><span class="line">    <span class="keyword">var</span> firstName = <span class="string">&#x27;&#x27;</span>;  </span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">makeName</span> = <span class="keyword">function</span>(<span class="params">first</span>)&#123;  </span><br><span class="line">        firstName = first;  </span><br><span class="line">    &#125;  </span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">$get</span> = <span class="keyword">function</span>(<span class="params"></span>) &#123;  </span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">function</span>(<span class="params">name</span>) &#123;  </span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(firstName + name);  </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;) </span><br><span class="line">.<span class="title function_">config</span>(<span class="keyword">function</span>(<span class="params">helloProvider</span>)&#123;  </span><br><span class="line">    <span class="comment">// 当前模块加载时执行</span></span><br><span class="line">    helloProvider.<span class="title function_">makeName</span>(<span class="string">&#x27;chuang&#x27;</span>);  </span><br><span class="line">&#125;) </span><br><span class="line">.<span class="title function_">run</span>([<span class="string">&quot;$rootScope&quot;</span>, <span class="string">&quot;$log&quot;</span>, <span class="keyword">function</span>(<span class="params">$rootScope, $log</span>)&#123;</span><br><span class="line">    <span class="comment">// 所有模块加载结束后执行</span></span><br><span class="line">    $rootScope.<span class="property">text</span> = <span class="string">&quot;Hello AngularJS&quot;</span>;</span><br><span class="line">    $log.<span class="title function_">log</span>(<span class="string">&quot;打印信息&quot;</span>);</span><br><span class="line">&#125;])</span><br><span class="line">.<span class="title function_">controller</span>(<span class="string">&#x27;MyCtrl&#x27;</span>, [ <span class="string">&#x27;$scope&#x27;</span>, <span class="string">&#x27;hello&#x27;</span>,<span class="string">&#x27;format&#x27;</span>, <span class="string">&#x27;service&#x27;</span>,</span><br><span class="line">    <span class="keyword">function</span> (<span class="params">$scope, hello, format, service</span>) &#123;</span><br><span class="line">        <span class="title function_">hello</span>(<span class="string">&#x27;Li&#x27;</span>);</span><br><span class="line">        <span class="title function_">format</span>(&#123; <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span>, <span class="attr">age</span>: <span class="number">10</span> &#125;);</span><br><span class="line">        service.<span class="title function_">test</span>();</span><br><span class="line"></span><br><span class="line">        $scope.<span class="property">name</span> = <span class="string">&quot;Mike&quot;</span>;</span><br><span class="line">        $scope.<span class="property">setName</span> = <span class="keyword">function</span>(<span class="params">name</span>)&#123;</span><br><span class="line">            $scope.<span class="property">name</span> = name;</span><br><span class="line">        &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">])</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 注入路由模块：ngRoute 不能进行视图嵌套，而且功能有限</span></span><br><span class="line">angular.<span class="title function_">module</span>(<span class="string">&#x27;App&#x27;</span>, [<span class="string">&#x27;ngRoute&#x27;</span>])</span><br><span class="line"><span class="comment">// 配置路由模块</span></span><br><span class="line">.<span class="title function_">config</span>([<span class="string">&#x27;$routeProvider&#x27;</span>, <span class="keyword">function</span>(<span class="params">$routeProvider</span>)&#123;</span><br><span class="line">    $routeProvider</span><br><span class="line">    <span class="comment">// 路由配置对象：路径区分大小写，&lt;a href=&quot;#/&quot;&gt;首页&lt;/a&gt;</span></span><br><span class="line">    .<span class="title function_">when</span>(<span class="string">&#x27;/&#x27;</span>, &#123;</span><br><span class="line">        <span class="attr">controller</span>: <span class="string">&#x27;HomeController&#x27;</span>,</span><br><span class="line">        <span class="attr">controllerAs</span>: <span class="string">&#x27;home&#x27;</span>,            <span class="comment">// 控制器别名</span></span><br><span class="line">        <span class="attr">template</span>: <span class="string">&#x27;&lt;h1&gt;首页&lt;/h1&gt;&#x27;</span>,</span><br><span class="line">        <span class="attr">templateUrl</span>: <span class="string">&#x27;/home.html&#x27;</span></span><br><span class="line">        <span class="attr">redirectTo</span>: <span class="string">&#x27;string、function&#x27;</span>,  <span class="comment">// 重定向</span></span><br><span class="line">        <span class="attr">params</span>: &#123; <span class="attr">_id</span>: <span class="literal">null</span> &#125;,           <span class="comment">// 传递参数</span></span><br><span class="line">        <span class="attr">resolve</span>: object&lt;key, fn&gt;  <span class="comment">// controller 依赖的其他模块</span></span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="comment">// 配置路由之外的其他路径指向</span></span><br><span class="line">    .<span class="title function_">otherwise</span>(<span class="string">&#x27;/&#x27;</span>)</span><br><span class="line">    .<span class="title function_">otherwise</span>(&#123;<span class="attr">redirectTo</span>: <span class="string">&#x27;/&#x27;</span>&#125;)</span><br><span class="line">&#125;])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// UI-Router 是基于 ngRouter 开发的第三方路由模块</span></span><br><span class="line">angular.<span class="title function_">module</span>(<span class="string">&quot;myApp&quot;</span>, [<span class="string">&quot;ui.router&quot;</span>])</span><br><span class="line">.<span class="title function_">config</span>(<span class="string">&#x27;$stateProvider&#x27;</span>, <span class="keyword">function</span> (<span class="params">$stateProvider</span>) &#123;</span><br><span class="line">    $stateProvider</span><br><span class="line">    <span class="title function_">state</span>(<span class="string">&quot;index&quot;</span>, &#123;</span><br><span class="line">        <span class="attr">url</span>: <span class="string">&#x27;/index&#x27;</span>,  </span><br><span class="line">        <span class="attr">views</span>:&#123;</span><br><span class="line">            <span class="string">&#x27;header&#x27;</span>: &#123; <span class="attr">template</span>: <span class="string">&quot;&lt;div&gt;头部内容&lt;/div&gt;&quot;</span> &#125;,</span><br><span class="line">            <span class="string">&#x27;nav&#x27;</span>: &#123; <span class="attr">template</span>: <span class="string">&quot;&lt;div&gt;菜单内容&lt;/div&gt;&quot;</span> &#125;,</span><br><span class="line">            <span class="string">&#x27;body&#x27;</span>: &#123; <span class="attr">template</span>:<span class="string">&quot;&lt;div&gt;展示内容&lt;/div&gt;&quot;</span> &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)   </span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">&lt;div ng-app=<span class="string">&quot;myApp&quot;</span> &gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">a</span> <span class="attr">ui-sref</span>=<span class="string">&quot;index&quot;</span>&gt;</span>显示首页<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">ui-view</span>=<span class="string">&quot;header&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span>  </span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">ui-view</span>=<span class="string">&quot;nav&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span>  </span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">ui-view</span>=<span class="string">&quot;body&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span>      </span><br><span class="line">&lt;/div&gt; </span><br></pre></td></tr></table></figure>


<h1 id="三、环境部署"><a href="#三、环境部署" class="headerlink" title="三、环境部署"></a>三、环境部署</h1><h2 id="SSH-登录"><a href="#SSH-登录" class="headerlink" title="SSH 登录"></a>SSH 登录</h2><blockquote>
<p>secure shell protocol，一种专为远程登录会话等网络服务提供的安全性协议，默认使用 22 端口并采用密文形式传输，相比 ftp、pop、telnet 等传统服务具有更高的安全性，主要用于提供类似 Telnet 的远程登录服务、类似 FTP 的传输数据服务。</p>
</blockquote>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 通过用户名密码登陆：监听端口 (默认 22)、远程机器的用户名、地址 (IP/域名/别名)</span></span><br><span class="line"><span class="comment"> * 服务器修改配置后重新连接需删除连接缓存文件 /User/yonyou/.ssh/known_hosts</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line">ssh user@remote [-p port]</span><br><span class="line">ssh root@<span class="number">172.20</span><span class="number">.45</span><span class="number">.133</span></span><br><span class="line">ssh root@<span class="number">10.16</span><span class="number">.1</span><span class="number">.68</span> -p <span class="number">49622</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过密钥免密登陆：客户端生成一对密钥、将公钥传到服务器端、免密登陆</span></span><br><span class="line"><span class="comment">// -t 指定 rsa/dsa 加密方式、-P 指定加密密码、-f 指定私钥地址</span></span><br><span class="line">ssh-keygen –t rsa [-P <span class="string">&#x27; &#x27;</span> ] [-f <span class="string">&quot;~/.ssh/id_rsa&quot;</span>]</span><br><span class="line">ssh-keygen -t dsa -f ~<span class="regexp">/.ssh/i</span>d_dsa</span><br><span class="line">ls ~<span class="regexp">/.ssh/i</span>d_rsa</span><br><span class="line">cat id_dsa.<span class="property">pub</span>         <span class="comment">// 查看公钥</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 将客户端的公钥传到服务器端实现免密登陆</span></span><br><span class="line">ssh-copy-id -i id_dsa.<span class="property">pub</span> root@<span class="number">172.20</span><span class="number">.45</span><span class="number">.133</span></span><br><span class="line">ssh root@<span class="number">172.20</span><span class="number">.45</span><span class="number">.133</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 多台客户端的免密登录</span></span><br><span class="line">scp ~<span class="regexp">/.ssh/i</span>d_rsa.<span class="property">pub</span> <span class="number">172.17</span><span class="number">.253</span><span class="number">.23</span></span><br><span class="line">cat id_rsa.<span class="property">pub</span> &gt;&gt; ~<span class="regexp">/.ssh/</span>authorized_keys</span><br></pre></td></tr></table></figure>

<h2 id="Docker-部署"><a href="#Docker-部署" class="headerlink" title="Docker 部署"></a>Docker 部署</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、安装配置：相关配置如下图</span></span><br><span class="line"><span class="comment">// 查找磁盘空间最大的路径，将文件 yyumif.zip 拖拽在对应路径</span></span><br><span class="line">df -h</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">* 目录说明</span></span><br><span class="line"><span class="comment">* client：应用服务，主要有 socket 服务、网关、正式环境、测试环境。</span></span><br><span class="line"><span class="comment">* server：数据库服务</span></span><br><span class="line"><span class="comment">* install-docker.sh：启动命令</span></span><br><span class="line"><span class="comment">* docker-18.06.3-ce.tgz：安装包</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line">unzip yyumif.<span class="property">zip</span></span><br><span class="line">cd yyumif</span><br><span class="line">sh install-docker.<span class="property">sh</span> docker-<span class="number">18.06</span><span class="number">.3</span>-ce.<span class="property">tgz</span>  <span class="comment">// 安装 docker</span></span><br><span class="line">docker ps -a    <span class="comment">// 查看所有容器详情</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2-1、启动数据库服务：查看安装路径是否和 sh 文件的一致，不同则修改</span></span><br><span class="line">cd yyumif/server</span><br><span class="line">vi/vim mongo.<span class="property">sh</span>    <span class="comment">// vim 是升级版本、i 编辑模式、:q 不保存退出、:wq 保存退出</span></span><br><span class="line">sh mongo.<span class="property">sh</span>        <span class="comment">// 启动数据库服务</span></span><br><span class="line">docker ps          <span class="comment">// 查看启动的服务、会显示服务对应 CONTAINER_ID </span></span><br><span class="line">docker logs -f e89687a98dce    <span class="comment">// 查看实时日志</span></span><br><span class="line">docker stop e89687a98dce       <span class="comment">// 停止服务</span></span><br><span class="line">docker rm e89687a98dce         <span class="comment">// 删除服务</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 2-2、启动其他服务：socket、正式环境、测试环境、网关</span></span><br><span class="line">cd yyumif/client</span><br><span class="line">sh web-socket.<span class="property">sh</span></span><br><span class="line">sh umif.<span class="property">sh</span> <span class="number">172.20</span><span class="number">.26</span><span class="number">.19</span></span><br><span class="line">sh umif-test.<span class="property">sh</span> <span class="number">172.20</span><span class="number">.26</span><span class="number">.19</span></span><br><span class="line">sh gateway.<span class="property">sh</span> <span class="number">172.20</span><span class="number">.26</span><span class="number">.19</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> 3、报错：防火墙没有关、解压镜像失败。</span></span><br><span class="line"><span class="comment"> * 两种解决方法：重启 docker 放开需要的端口、关闭防火墙。</span></span><br><span class="line"><span class="comment"> * 实现方式：关闭防火墙如下</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line">systemctl stop iptables</span><br><span class="line">chkconfig iptables off  </span><br><span class="line">yum install iptables-services  <span class="comment">// 安装要卸载防火墙的软件</span></span><br><span class="line">systemctl status iptables      <span class="comment">// 查看</span></span><br><span class="line">chkconfig iptables off         <span class="comment">// 永久关闭防火墙</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// server/common/umif-test 旧版本缺少文件</span></span><br><span class="line">config/lib/minio.<span class="property">js</span></span><br><span class="line">config/env/iot.<span class="property">js</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 4-1、更新补丁：umif-test 目录下替换 public、modules</span></span><br><span class="line">ssh root@<span class="number">172.20</span><span class="number">.45</span><span class="number">.133</span></span><br><span class="line">cd data1/client/common/umif-test</span><br><span class="line">docker ps </span><br><span class="line">docker restart e89687a98dce</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4-2、更新依赖包：node_modules 压缩包替换</span></span><br><span class="line">ssh root@<span class="number">10.16</span><span class="number">.1</span><span class="number">.68</span> -p <span class="number">49622</span></span><br><span class="line">cd /data1/client/code/umif-lsc</span><br><span class="line">unzip -o node_modules</span><br></pre></td></tr></table></figure>

  <div align="center">
      <img src="" data-original="/images/web/gateway.png" alt="相关配置" width="100%">
  </div>


<h1 id="四、MongoDB"><a href="#四、MongoDB" class="headerlink" title="四、MongoDB"></a>四、MongoDB</h1><blockquote>
<p>一个基于分布式文件存储的数据库，是非关系数据库中功能最丰富、最像关系数据库的。它由 C++ 语言编写，支持基于 json 扩展的 bson 格式来描述无结构化的数据类型，可存储复杂的数据类型，使用时可搭配可视化管理工具 Window MongoChef、Mac Navicat-Premium。</p>
</blockquote>
<h2 id="基础了解"><a href="#基础了解" class="headerlink" title="基础了解"></a>基础了解</h2><ul>
<li><strong>核心概念</strong>：数据库（仓库）、集合（数据）、文档（最小单位）。</li>
<li><strong>主要特点</strong>：高性能、易部署、易使用，数据存储方便，但不支持事务和空间占用大。</li>
<li><strong>适用场景</strong>：网站实时数据处理、基础缓存层（避免下层的数据源过载）、高伸缩性。</li>
<li><strong>不适用场景</strong>：高度事务性的系统、传统的商业智能应用、复杂的跨文档&#x2F;表级联查询。</li>
</ul>
<h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><ul>
<li><strong>ObjectID</strong>：文档添加时自动生成的唯一 _id，类似主键的唯一 key。</li>
<li><strong>String</strong>：UTF-8 字符串。UTF-8 是针对 Unicode 的一种可变长度字符编码。</li>
<li><strong>Boolean</strong>：布尔值，取值 true、false。</li>
<li><strong>Integer</strong>：整数，常用 Int32、Int64。</li>
<li><strong>Double</strong>：浮点数，所有小数都是 Double。</li>
<li><strong>Arrays</strong>：数组&#x2F;列表，多个值存储到一个键。</li>
<li><strong>Object</strong>：字典，形式为 key-value。</li>
<li><strong>Null</strong>：空数据</li>
<li><strong>Timestamp</strong>：时间戳</li>
<li><strong>Date</strong>：日期</li>
</ul>
<h2 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 帮助命令：全局、数据库相关、集合相关</span></span><br><span class="line">help  </span><br><span class="line">db.<span class="title function_">help</span>()</span><br><span class="line">db.集合名.<span class="title function_">help</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数据库操作：启动、查询、创建、删除</span></span><br><span class="line">mongo </span><br><span class="line">show dbs/databases</span><br><span class="line">use my_user</span><br><span class="line">db.<span class="title function_">dropDatabase</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 集合操作：新建、查看、删除</span></span><br><span class="line">db.<span class="title function_">createCollection</span>(<span class="string">&#x27;number&#x27;</span>)</span><br><span class="line">show collections</span><br><span class="line">db.<span class="property">collectionName</span>.<span class="title function_">drop</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 文档操作：新增、删除、修改、查询。修改器有 $inc 增减、$set 修改字段。</span></span><br><span class="line">db.<span class="property">collectionName</span>.<span class="title function_">insert</span>()</span><br><span class="line">db.<span class="property">collectionName</span>.<span class="title function_">remove</span>()</span><br><span class="line">db.<span class="property">collectionName</span>.<span class="title function_">update</span>(条件, 新文档, 是否新增, 是否修改多条)</span><br><span class="line">db.<span class="property">collectionName</span>.<span class="title function_">update</span>(条件, &#123;修改器名称: &#123;修改键: 新值&#125;&#125;)</span><br><span class="line">db.<span class="property">collectionName</span>.<span class="property">find</span>、<span class="title function_">findOne</span>(条件)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加文档</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">insert</span>(&#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;xiaobai&#x27;</span>,<span class="string">&#x27;age&#x27;</span>: <span class="number">10</span>&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 删除文档</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">remove</span>(&#123;<span class="attr">age</span>:<span class="number">20</span>&#125;)</span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">remove</span>(&#123;<span class="attr">age</span>: &#123;<span class="string">&#x27;$lt&#x27;</span>: <span class="number">6</span>&#125; &#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 更新文档</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">update</span>(&#123;<span class="attr">age</span>:<span class="number">18</span>&#125;, &#123;<span class="attr">name</span>:<span class="string">&#x27;xiaobai&#x27;</span>&#125;)</span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">update</span>(&#123;<span class="attr">age</span>:<span class="number">10</span>&#125;, &#123;<span class="attr">name</span>:<span class="string">&#x27;xiaoli&#x27;</span>&#125;, <span class="literal">true</span>, <span class="literal">true</span>)</span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">update</span>(&#123;<span class="attr">age</span>:<span class="number">6</span>&#125;, &#123;<span class="attr">$set</span>: &#123;<span class="attr">name</span>: <span class="string">&#x27;s&#x27;</span>&#125;&#125; )   <span class="comment">// 修改字段</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">update</span>(&#123;<span class="attr">age</span>:<span class="number">10</span>&#125;, &#123;<span class="attr">$inc</span>: &#123;<span class="attr">age</span>:<span class="number">10</span>&#125;&#125;)      <span class="comment">// 年龄增加十岁</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 查询文档</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">age</span>: <span class="number">6</span>&#125;)</span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">age</span>: &#123;<span class="attr">$gte</span>: <span class="number">3</span>, <span class="attr">$lte</span>: <span class="number">9</span>&#125;&#125;)</span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;&#125;, &#123;<span class="attr">age</span>: <span class="number">1</span>&#125;)           <span class="comment">// 1、0 表示年龄的显示和隐藏</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>().<span class="title function_">sort</span>(&#123;<span class="attr">age</span>: -<span class="number">1</span>&#125;)       <span class="comment">// 1、-1 根据年龄进行升序和降序</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>().<span class="title function_">limit</span>(<span class="number">3</span>)              <span class="comment">// 前三条数据</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>().<span class="title function_">skip</span>(<span class="number">2</span>).<span class="title function_">limit</span>(<span class="number">3</span>)      <span class="comment">// 3-5 条数据</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">age</span>: <span class="number">1</span>&#125;).<span class="title function_">count</span>()       <span class="comment">// 统计数据个数</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>().<span class="title function_">limit</span>(<span class="number">5</span>).<span class="title function_">count</span>(<span class="literal">true</span>)  <span class="comment">// 限制后需使用 true、非0</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">distinct</span>(<span class="string">&#x27;age&#x27;</span>)              <span class="comment">// 去重字段 age</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">$where</span>: <span class="keyword">function</span>(<span class="params"></span>)&#123;    <span class="comment">// 自定义查询</span></span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">age</span>&gt;<span class="number">20</span></span><br><span class="line">&#125;&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 排序：1 升序、-1 降序。</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>().<span class="title function_">sort</span>(&#123; <span class="attr">age</span>: <span class="number">1</span> &#125;)</span><br></pre></td></tr></table></figure>

<h2 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h2><ul>
<li><strong>比较</strong>：$eq $ne (不)等于、$gt $gte 大于(等于)、$lt $lte 小于(等于)、$in $nin (不)包含。</li>
<li><strong>逻辑</strong>：$and 都匹配、$not 不匹配、$or 任一匹配、$nor 无一匹配。</li>
<li><strong>元素</strong>：$exists 字段存在、$type 指定字段类型。</li>
<li><strong>评估</strong>：$where 匹配表达式、$regex 匹配正则表达式、$text 匹配文本搜索、$expr 支持查询条件中使用表达式、$mod 指定模运算结果、$jsonSchema 验证 JSON 规范。</li>
<li><strong>地理空间查询</strong>：$geoIntersects 几何相交、$geoWithin 边界几何内、$near 返回点附近的地理空间对象、$nearSphere	返回球体上某个点附近的地理空间对象。</li>
<li><strong>数组查询</strong>：$all 包含所有指定元素、$elemMatch 元素符合所有条件、$size 指定元素大小。</li>
<li><strong>按位查询</strong>：$bitsAllClear、$bitsAllSet、$bitsAnyClear、$bitsAnySet。</li>
<li><strong>投影</strong>：返回包含指定字段的集合，$	内容匹配的第一个、$elemMatch 条件匹配的第一个、$meta 访问文本搜索元数据、$slice 指定元素的数量和范围。</li>
</ul>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 年龄为 20-50 岁的男人</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">$and</span>: [&#123;<span class="string">&quot;sex&quot;</span>: <span class="number">1</span>&#125;, &#123;<span class="attr">age</span>: &#123;<span class="attr">$gt</span>: <span class="number">20</span>, <span class="attr">$lt</span>: <span class="number">50</span>&#125;&#125;]&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 年龄大于 30 岁的或者工资小于 1000</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">$or</span>: [&#123;<span class="string">&quot;age&quot;</span>: &#123;<span class="attr">$gt</span>:<span class="number">30</span>&#125;&#125;, &#123;<span class="attr">salary</span>: &#123;<span class="attr">$lte</span>: <span class="number">1000</span>&#125;&#125;]&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 年龄不大于 30 岁，并且工资不小于 1000</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123;<span class="attr">$nor</span>: [&#123;<span class="string">&quot;age&quot;</span>: &#123;<span class="attr">$gt</span>: <span class="number">30</span>&#125;&#125;, &#123;<span class="attr">salary</span>: &#123;<span class="attr">$lte</span>: <span class="number">1000</span>&#125;&#125;]&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 年龄为 25 或 30 岁的</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>( &#123;<span class="attr">age</span>: &#123;<span class="attr">$in</span>: [<span class="number">25</span>, <span class="number">30</span>]&#125;&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 包含 name 字段的</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123; <span class="string">&quot;name&quot;</span>: &#123;<span class="attr">$exists</span>: <span class="literal">true</span>&#125;&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 年龄大于 30</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123; <span class="attr">age</span>: &#123;<span class="attr">$not</span>: &#123;<span class="attr">$lte</span>: <span class="number">20</span>&#125; &#125; &#125;) </span><br><span class="line"></span><br><span class="line"><span class="comment">// 姓名为 Null：1 数字、2 字符、3 对象、4 数组等</span></span><br><span class="line">db.<span class="property">user</span>.<span class="title function_">find</span>(&#123; <span class="attr">name</span>: &#123;<span class="attr">$type</span>: <span class="number">10</span>&#125; &#125;)</span><br></pre></td></tr></table></figure>

<h2 id="聚合查询"><a href="#聚合查询" class="headerlink" title="聚合查询"></a>聚合查询</h2>  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> 聚合运算符</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $match：查询条件</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $group：分组数据</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $sort：排序后输出</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $skip/$limit：跳过和限制，常用于分页查询。</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $project：映射数据，对数据增删改或计算。</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $lookup：多表关联查询，新增一个数组字段。</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $unwind：将 $lookup 生成的数组文档拆分。 </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $addFields：自定义新字段</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> $group: &#123; _id: &#x27;$字段&#x27;, 自定义字段: &#123;操作符: &#x27;$字段&#x27;&#125;</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $sum、$avg、$min、$max、$first、$last、$push $addToSet</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> $push 元素可重复、$addToSet 元素不可重复、聚合结果使用别名</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> $unwind </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> preserveNullAndEmptyArrays：处理空数组、非数组、无字段、null</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> $project: &#123;_id: 0, name: 1, price: 1 &#125;</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> 0 删除 1 新增、重命名格式 &#123;新字段: &#x27;$旧字段&#x27;&#125;</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@title</span> <span class="variable">$lookup</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> from 关联的附表、localField 主表查询字段、foreignField </span></span><br><span class="line"><span class="comment"> * 附表查询字段、as 新增字段、pipeline 连接的集合管道、let 管道变量</span></span><br><span class="line"><span class="comment">**/</span></span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;苹果&quot;</span>, <span class="attr">price</span>: <span class="number">10</span>, <span class="title class_">Qty</span>: <span class="number">2</span> &#125;,</span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;橙子&quot;</span>, <span class="attr">price</span>: <span class="number">15</span>, <span class="title class_">Qty</span>: <span class="number">3</span> &#125;,</span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;香蕉&quot;</span>, <span class="attr">price</span>: <span class="number">10</span>, <span class="title class_">Qty</span>: <span class="number">1</span> &#125;,</span><br><span class="line">&gt; db.<span class="property">goods</span>.<span class="title function_">aggregate</span>(<span class="params">&#123;</span></span><br><span class="line"><span class="params">    $group: &#123;</span></span><br><span class="line"><span class="params">        _id: <span class="literal">null</span>,  // 将所有数据分为一组</span></span><br><span class="line"><span class="params">        totalPrice: &#123; $sum: &#123; $multiply: [<span class="string">&quot;price&quot;</span>, <span class="string">&quot;Qty&quot;</span>] &#125; &#125;,</span></span><br><span class="line"><span class="params">        avgageQty: &#123; $avg: $Qty &#125;,</span></span><br><span class="line"><span class="params">        count: &#123; $sum: <span class="number">1</span> &#125;</span></span><br><span class="line"><span class="params">    &#125;</span></span><br><span class="line"><span class="params">&#125;</span>)</span><br><span class="line">&#123; <span class="attr">_id_</span>: <span class="literal">null</span>, <span class="attr">totalPrice</span>: <span class="number">75</span>, <span class="attr">avgageQty</span>: <span class="number">2</span>, <span class="attr">count</span>: <span class="number">3</span> &#125;</span><br><span class="line">&gt; db.<span class="property">goods</span>.<span class="title function_">aggregate</span>(<span class="params">&#123;</span></span><br><span class="line"><span class="params">    $group: &#123; _id: <span class="string">&quot;$price&quot;</span>, names: &#123;$push: <span class="string">&quot;$name&quot;</span>&#125; &#125;</span></span><br><span class="line"><span class="params">    // 多字段分组：_id: &#123; price: <span class="string">&quot;$price&quot;</span>, Qty: <span class="string">&quot;$Qty&quot;</span> &#125;</span></span><br><span class="line"><span class="params">&#125;</span>)</span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">10</span>, <span class="attr">names</span>: [<span class="string">&quot;苹果&quot;</span>, <span class="string">&quot;香蕉&quot;</span>] &#125;  &#123; <span class="attr">_id</span>: <span class="number">15</span>, <span class="attr">names</span>: [<span class="string">&quot;橙子&quot;</span>] &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 分组和重命名</span></span><br><span class="line">db.<span class="property">students</span>.<span class="title function_">aggregate</span>(<span class="params"></span></span><br><span class="line"><span class="params">  &#123; $group: &#123;_id: <span class="string">&#x27;$gender&#x27;</span>, avg: &#123;$avg: <span class="string">&#x27;$age&#x27;</span>&#125;&#125;&#125;, </span></span><br><span class="line"><span class="params">  &#123; $project: &#123;_id: <span class="number">0</span>, gender: <span class="string">&#x27;$_id&#x27;</span>, avg_age: <span class="string">&#x27;$avg&#x27;</span>&#125;&#125;</span></span><br><span class="line"><span class="params"></span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span>, <span class="attr">score</span>: <span class="number">90</span>, <span class="attr">subject</span>: [<span class="string">&quot;语文&quot;</span>, <span class="string">&quot;数学&quot;</span>] &#125;</span><br><span class="line">&gt; db.<span class="property">students</span>.<span class="title function_">aggregate</span>(&#123; <span class="attr">$unwind</span>: $subject &#125;)</span><br><span class="line">&gt; db.<span class="property">students</span>.<span class="title function_">aggregate</span>(<span class="params">&#123;</span></span><br><span class="line"><span class="params">    $unwind: &#123;path: <span class="string">&#x27;$subject&#x27;</span>, preserveNullAndEmptyArrays: <span class="literal">true</span> &#125;</span></span><br><span class="line"><span class="params">&#125;</span>)</span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span>, <span class="attr">score</span>: <span class="number">90</span>, <span class="attr">subject</span>: <span class="string">&quot;语文&quot;</span> &#125;</span><br><span class="line">&#123; <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span>, <span class="attr">score</span>: <span class="number">90</span>, <span class="attr">subject</span>: <span class="string">&quot;数学&quot;</span> &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// orders 表</span></span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">1</span>, <span class="attr">product_id</span>: <span class="number">154</span>, <span class="attr">status</span>: <span class="number">1</span> &#125;</span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">2</span>, <span class="attr">product_id</span>: <span class="number">155</span>, <span class="attr">status</span>: <span class="number">1</span> &#125;</span><br><span class="line"><span class="comment">// products 表</span></span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">154</span>, <span class="attr">name</span>: <span class="string">&quot;电脑&quot;</span> &#125;</span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">155</span>, <span class="attr">name</span>: <span class="string">&quot;耳机&quot;</span> &#125;</span><br><span class="line"><span class="comment">// $lookup 多表查询</span></span><br><span class="line">db.<span class="property">orders</span>.<span class="title function_">aggregate</span>(<span class="params">[</span></span><br><span class="line"><span class="params">  &#123; $lookup: &#123;</span></span><br><span class="line"><span class="params">        <span class="keyword">from</span>: <span class="string">&#x27;products&#x27;</span>,</span></span><br><span class="line"><span class="params">        localField: <span class="string">&#x27;product_id&#x27;</span>,</span></span><br><span class="line"><span class="params">        foreignField: <span class="string">&#x27;_id&#x27;</span>,</span></span><br><span class="line"><span class="params">        <span class="keyword">as</span>: <span class="string">&#x27;orderLists&#x27;</span></span></span><br><span class="line"><span class="params">  &#125;&#125;,</span></span><br><span class="line"><span class="params">  &#123; $match: &#123; product_id: <span class="number">154</span> &#125; &#125;</span></span><br><span class="line"><span class="params">]</span>)</span><br><span class="line">&#123; <span class="attr">_id</span>: <span class="number">1</span>, </span><br><span class="line">  <span class="attr">product_id</span>: <span class="number">154</span>, </span><br><span class="line">  <span class="attr">status</span>: <span class="number">1</span>, </span><br><span class="line">  <span class="attr">orderLists</span>: [&#123; <span class="attr">_id</span>: <span class="number">154</span>, <span class="attr">name</span>: <span class="string">&quot;笔记本电脑&quot;</span> &#125;] </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义新字段</span></span><br><span class="line">&#123; <span class="attr">$addFields</span>: &#123; </span><br><span class="line">      <span class="title class_">DisTime</span>: &#123; <span class="attr">$dateToString</span>: &#123; </span><br><span class="line">          <span class="string">&quot;format&quot;</span>: <span class="string">&quot;%Y-%m-%d&quot;</span>, </span><br><span class="line">          <span class="string">&quot;date&quot;</span>: <span class="string">&quot;$DistributionTime&quot;</span> </span><br><span class="line">      &#125;&#125;</span><br><span class="line">  &#125;&#125;,</span><br></pre></td></tr></table></figure>










    </div>

    
    
    <div>
      
        <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;margin-top:20px;">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div>
    
</div>

      
    </div>
    
        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>chuangges
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="https://chuangges.gitee.io/2020/12/10/15-%E6%99%BA%E8%83%BD%E5%B7%A5%E5%8E%82/" title="智能工厂">https://chuangges.gitee.io/2020/12/10/15-智能工厂/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/zh_CN" rel="external nofollow noopener noreferrer" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>


      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/11/11/5-3-vue%E9%AB%98%E9%98%B6%E6%8A%80%E8%83%BD/" rel="prev" title="Vue 高阶技能">
      <i class="fa fa-chevron-left"></i> Vue 高阶技能
    </a></div>
      <div class="post-nav-item">
    <a href="/2022/08/26/16-Nginx/" rel="next" title="Nginx 基础使用">
      Nginx 基础使用 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91"><span class="nav-number">1.</span> <span class="nav-text">一、项目开发</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BC%80%E5%8F%91%E5%87%86%E5%A4%87"><span class="nav-number">1.1.</span> <span class="nav-text">开发准备</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91"><span class="nav-number">1.2.</span> <span class="nav-text">应用开发</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9F%A5%E8%AF%A2%E4%BC%98%E5%8C%96"><span class="nav-number">1.3.</span> <span class="nav-text">查询优化</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#gulp-%E9%85%8D%E7%BD%AE"><span class="nav-number">1.4.</span> <span class="nav-text">gulp 配置</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81AngularJS"><span class="nav-number">2.</span> <span class="nav-text">二、AngularJS</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"><span class="nav-number">2.1.</span> <span class="nav-text">核心概念</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%87%8D%E8%A6%81%E5%AF%B9%E8%B1%A1"><span class="nav-number">2.2.</span> <span class="nav-text">重要对象</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8C%87%E4%BB%A4"><span class="nav-number">2.3.</span> <span class="nav-text">指令</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%BF%87%E6%BB%A4%E5%99%A8"><span class="nav-number">2.4.</span> <span class="nav-text">过滤器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9C%8D%E5%8A%A1"><span class="nav-number">2.5.</span> <span class="nav-text">服务</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%B7%AF%E7%94%B1"><span class="nav-number">2.6.</span> <span class="nav-text">路由</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%89%E3%80%81%E7%8E%AF%E5%A2%83%E9%83%A8%E7%BD%B2"><span class="nav-number">3.</span> <span class="nav-text">三、环境部署</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#SSH-%E7%99%BB%E5%BD%95"><span class="nav-number">3.1.</span> <span class="nav-text">SSH 登录</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Docker-%E9%83%A8%E7%BD%B2"><span class="nav-number">3.2.</span> <span class="nav-text">Docker 部署</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%9B%9B%E3%80%81MongoDB"><span class="nav-number">4.</span> <span class="nav-text">四、MongoDB</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%9F%BA%E7%A1%80%E4%BA%86%E8%A7%A3"><span class="nav-number">4.1.</span> <span class="nav-text">基础了解</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-number">4.2.</span> <span class="nav-text">数据类型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4"><span class="nav-number">4.3.</span> <span class="nav-text">常用命令</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%BF%90%E7%AE%97%E7%AC%A6"><span class="nav-number">4.4.</span> <span class="nav-text">运算符</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2"><span class="nav-number">4.5.</span> <span class="nav-text">聚合查询</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="chuangges" src="" data-original="/images/chuang.png">
  <p class="site-author-name" itemprop="name">chuangges</p>
  <div class="site-description" itemprop="description">chuangge's blog.</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">39</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">7</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">7</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/chuangges" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;chuangges" rel="external nofollow noopener noreferrer" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://stackoverflow.com/yourname" title="StackOverflow → https:&#x2F;&#x2F;stackoverflow.com&#x2F;yourname" rel="external nofollow noopener noreferrer" target="_blank"><i class="fab fa-stack-overflow fa-fw"></i>StackOverflow</a>
      </span>
  </div>


  <div class="links-of-blogroll motion-element">
    <div class="links-of-blogroll-title"><i class="fa fa-link fa-fw"></i>
      友情链接
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://juejin.im/" title="https:&#x2F;&#x2F;juejin.im&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">掘金</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://www.nowcoder.com/" title="https:&#x2F;&#x2F;www.nowcoder.com&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">牛客网</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://www.docschina.org/" title="https:&#x2F;&#x2F;www.docschina.org&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">印记中文</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="http://tool.lu/" title="http:&#x2F;&#x2F;tool.lu&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">在线工具</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://tinypng.com/" title="https:&#x2F;&#x2F;tinypng.com&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">图片压缩</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://bigjpg.com/" title="https:&#x2F;&#x2F;bigjpg.com&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">图片放大</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://tool.chinaz.com/" title="https:&#x2F;&#x2F;tool.chinaz.com&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">站长工具</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://learn-anything.xyz/" title="https:&#x2F;&#x2F;learn-anything.xyz&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">Learn-Anything</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="https://stackoverflow.com/" title="https:&#x2F;&#x2F;stackoverflow.com&#x2F;" rel="external nofollow noopener noreferrer" target="_blank">Stack-Overflow</a>
        </li>
    </ul>
  </div>

      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2024</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">chuangge</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-area"></i>
    </span>
    <span title="站点总字数">1m</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
    <span title="站点阅读时长">15:14</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="external nofollow noopener noreferrer" target="_blank">Hexo</a> & <a href="https://pisces.theme-next.org/" class="theme-link" rel="external nofollow noopener noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","model":{"jsonPath":"/live2dw/assets/tororo.model.json"},"display":{"position":"left","width":180,"height":360},"mobile":{"show":false},"react":{"opacityDefault":1,"opacityOnHover":1},"log":false,"tagMode":false});</script>
        <style>
            [bg-lazy] {
                background-image: none !important;
                background-color: #eee !important;
            }
        </style>
        <script>
            window.imageLazyLoadSetting = {
                isSPA: false,
                preloadRatio: 1,
                processImages: null,
            };
        </script><script>window.addEventListener("load",function(){var t=/\.(gif|jpg|jpeg|tiff|png)$/i,r=/^data:image\/[a-z]+;base64,/;Array.prototype.slice.call(document.querySelectorAll("img[data-original]")).forEach(function(a){var e=a.parentNode;"A"===e.tagName&&(e.href.match(t)||e.href.match(r))&&(e.href=a.dataset.original)})});</script><script>!function(e){e.imageLazyLoadSetting.processImages=t;var n=e.imageLazyLoadSetting.isSPA,i=e.imageLazyLoadSetting.preloadRatio||1,r=o();function o(){var t=Array.prototype.slice.call(document.querySelectorAll("img[data-original]")),e=Array.prototype.slice.call(document.querySelectorAll("[bg-lazy]"));return t.concat(e)}function t(){n&&(r=o());for(var t,a=0;a<r.length;a++)0<=(t=(t=r[a]).getBoundingClientRect()).bottom&&0<=t.left&&t.top<=(e.innerHeight*i||document.documentElement.clientHeight*i)&&function(){var t,e,n,i,o=r[a];e=function(){r=r.filter(function(t){return o!==t})},(t=o).hasAttribute("bg-lazy")?(t.removeAttribute("bg-lazy"),e&&e()):(n=new Image,i=t.getAttribute("data-original"),n.onload=function(){t.src=i,t.removeAttribute("data-original"),e&&e()},t.src!==i&&(n.src=i))}()}function a(){clearTimeout(t.tId),t.tId=setTimeout(t,500)}t(),document.addEventListener("scroll",a),e.addEventListener("resize",a),e.addEventListener("orientationchange",a)}(this);</script></body>
</html>
